package com.inspur.edp.cef.designtime.api.increment.extractor;

import com.inspur.edp.cef.designtime.api.changecontrolrule.controlrule.basic.ControlRuleItem;
import com.inspur.edp.cef.designtime.api.changecontrolrule.controlruledef.basic.entity.ControlRuleDefItem;
import com.inspur.edp.cef.designtime.api.changecontrolrule.controlruledef.basic.entity.ControlRuleValue;
import com.inspur.edp.cef.designtime.api.collection.GspAssociationCollection;
import com.inspur.edp.cef.designtime.api.collection.GspEnumValueCollection;
import com.inspur.edp.cef.designtime.api.entity.MappingRelation;
import com.inspur.edp.cef.designtime.api.exceptions.CommonEntityErrorCodeEnum;
import com.inspur.edp.cef.designtime.api.exceptions.CommonEntityException;
import com.inspur.edp.cef.designtime.api.increment.property.AssoColPropIncrement;
import com.inspur.edp.cef.designtime.api.increment.property.BooleanPropertyIncrement;
import com.inspur.edp.cef.designtime.api.increment.property.EnumColIncrement;
import com.inspur.edp.cef.designtime.api.increment.property.IntPropertyIncrement;
import com.inspur.edp.cef.designtime.api.increment.property.MappingDicPropIncrement;
import com.inspur.edp.cef.designtime.api.increment.property.ObjectPropertyIncrement;
import com.inspur.edp.cef.designtime.api.increment.property.PropertyIncrement;
import com.inspur.edp.cef.designtime.api.increment.property.StringPropertyIncrement;
import org.springframework.util.ObjectUtils;

import java.util.HashMap;

public class ExtractUtils {

    public static void extractValue(
            HashMap<String, PropertyIncrement> propChange,
            String oldValue,
            String newValue,
            String propName,
            ControlRuleItem rule,
            ControlRuleDefItem ruleDefItem) {
        if (isEqual(oldValue,newValue))
            return;
        if (!isAllow(propName, oldValue, newValue, rule, ruleDefItem))
            return;

        StringPropertyIncrement increment = new StringPropertyIncrement(true);
        increment.setPropertyValue(newValue);
        propChange.put(propName, increment);
    }

    public static void extractValue(
            HashMap<String, PropertyIncrement> propChange,
            int oldValue,
            int newValue,
            String propName,
            ControlRuleItem rule,
            ControlRuleDefItem ruleDefItem) {
        if (oldValue == newValue)
            return;
        if (!isAllow(propName, oldValue, newValue, rule, ruleDefItem))
            return;

        IntPropertyIncrement increment = new IntPropertyIncrement(true);
        increment.setPropertyValue(newValue);
        propChange.put(propName, increment);
    }

    public static void extractValue(
            HashMap<String, PropertyIncrement> propChange,
            boolean oldValue,
            boolean newValue,
            String propName,
            ControlRuleItem rule,
            ControlRuleDefItem ruleDefItem) {
        if (oldValue==newValue)
            return;
        if (!isAllow(propName, oldValue, newValue, rule, ruleDefItem))
            return;

        BooleanPropertyIncrement increment = new BooleanPropertyIncrement(true);
        increment.setPropertyValue(newValue);
        propChange.put(propName, increment);
    }

    public static void extractValue(
            HashMap<String, PropertyIncrement> propChange,
            Object oldValue,
            Object newValue,
            String propName,
            ControlRuleItem rule,
            ControlRuleDefItem ruleDefItem) {
        if (oldValue.equals(newValue))
            return;
        if (!isAllow(propName, oldValue, newValue, rule, ruleDefItem))
            return;

        ObjectPropertyIncrement increment = new ObjectPropertyIncrement(true);
        increment.setPropertyValue(newValue);
        propChange.put(propName, increment);
    }

    public static void extractValue(
            HashMap<String, PropertyIncrement> propChange,
            GspEnumValueCollection oldValue,
            GspEnumValueCollection newValue,
            String propName,
            ControlRuleItem rule,
            ControlRuleDefItem ruleDefItem) {
        if (oldValue.equals(newValue))
            return;
        if (!isAllow(propName, oldValue, newValue, rule, ruleDefItem))
            return;

        EnumColIncrement increment = new EnumColIncrement(true);
        increment.setPropertyValue(newValue);
        propChange.put(propName, increment);
    }

    public static void extractValue(
            HashMap<String, PropertyIncrement> propChange,
            GspAssociationCollection oldValue,
            GspAssociationCollection newValue,
            String propName,
            ControlRuleItem rule,
            ControlRuleDefItem ruleDefItem) {
        if (oldValue.equals(newValue))
            return;
        if (!isAllow(propName, oldValue, newValue, rule, ruleDefItem))
            return;

        AssoColPropIncrement increment = new AssoColPropIncrement(true);
        increment.setPropertyValue(newValue);
        propChange.put(propName, increment);
    }
    public static void extractValue(
        HashMap<String, PropertyIncrement> propChange,
        MappingRelation oldValue,
        MappingRelation newValue,
        String propName,
        ControlRuleItem rule,
        ControlRuleDefItem ruleDefItem) {
        if (oldValue.equals(newValue))
            return;
        if (!isAllow(propName, oldValue, newValue, rule, ruleDefItem))
            return;

        MappingDicPropIncrement increment = new MappingDicPropIncrement(true);
        increment.setPropertyValue(newValue);
        propChange.put(propName, increment);
    }

    private static boolean isAllow(
            String propertyName, Object oldValue, Object newValue, ControlRuleItem rule, ControlRuleDefItem ruleDefItem) {
        if(rule == null && ruleDefItem == null)
            return true;
        if(rule == null)
            return ruleDefItem.getDefaultRuleValue() == ControlRuleValue.Allow;
        switch (rule.getControlRuleValue()) {
            case Allow:
                return true;
            case Forbiddon:
                return false;
            case Default:
                return ruleDefItem.getDefaultRuleValue() == ControlRuleValue.Allow;
            default:
                throw CommonEntityException.createException(CommonEntityErrorCodeEnum.GSP_BEMODEL_COMMON_ENTITY_0019, rule.getControlRuleValue().toString());
        }

    }


    public static void extractValueAllowShort(
            HashMap<String, PropertyIncrement> propChange,
            int oldValue,
            int newValue,
            String propName,
            ControlRuleItem rule,
            ControlRuleDefItem ruleDefItem) {

        if (oldValue == newValue)
            return;
        if (!isAllow(propName, oldValue, newValue, rule, ruleDefItem))
            return;
        if(newValue > oldValue) {
            throw CommonEntityException.createException(CommonEntityErrorCodeEnum.GSP_BEMODEL_COMMON_ENTITY_0020, propName);
        }
        IntPropertyIncrement increment = new IntPropertyIncrement(true);
        increment.setPropertyValue(newValue);
        propChange.put(propName, increment);
    }

    /**
     *
     * @param propChange
     * @param oldValue
     * @param newValue
     * @param propName
     * @param rule
     * @param ruleDefItem
     */
    public static void extracLengthtValue(HashMap<String, PropertyIncrement> propChange,int oldValue,int newValue,String propName,ControlRuleItem rule,ControlRuleDefItem ruleDefItem) {
        if (oldValue == newValue)
            return;
        if (!isAllow(propName, oldValue, newValue, rule, ruleDefItem))
            return;
        IntPropertyIncrement increment = new IntPropertyIncrement(true);
        increment.setPropertyValue(newValue);
        propChange.put(propName, increment);
    }

    public static void extractValueAllow2True(
            HashMap<String, PropertyIncrement> propChange,
            boolean oldValue,
            boolean newValue,
            String propName,
            ControlRuleItem rule,
            ControlRuleDefItem ruleDefItem) {

        if (oldValue == newValue) {
            return;
        }
        if (!isAllow(propName, oldValue, newValue, rule, ruleDefItem)) {
            return;
        }
        if(oldValue) {
            throw CommonEntityException.createException(CommonEntityErrorCodeEnum.GSP_BEMODEL_COMMON_ENTITY_0021, propName);
        }
        IntPropertyIncrement increment = new IntPropertyIncrement(true);
        increment.setPropertyValue(newValue);
        propChange.put(propName, increment);
    }


    private static boolean isEqual(Object oldValue, Object newValue){
        return ObjectUtils.nullSafeEquals(oldValue, newValue);
    }
}
